# Change needed: SRCS, VPATH, CFLAGS -I

#=============VARIABLES=============

# searching directories
VPATH = ./tools \
		./kernel/init \
		./kernel/libs \
		./kernel/batch \
		./kernel/mem \
		./kernel/trap \
		./kernel/driver \
		./kernel/proc \
		./kernel/fs \

SRCS = $(wildcard ./kernel/init/*.S ./kernel/init/*.c \
		./kernel/libs/*.S ./kernel/libs/*.c \
		./kernel/batch/*.S ./kernel/batch/*.c \
		./kernel/trap/*.S ./kernel/trap/*.c \
		./kernel/mem/*.S ./kernel/mem/*.c \
		./kernel/driver/*.S ./kernel/driver/*.c \
		./kernel/proc/*.S ./kernel/proc/*.c \
		./kernel/fs/*.S ./kernel/fs/*.c)
		
OBJS = $(addsuffix .o, $(basename $(SRCS)))
DFILES = $(addsuffix .d, $(basename $(SRCS)))

# make default variables denote the right tools
TOOLPREFIX = riscv64-unknown-elf-
CC = $(TOOLPREFIX)gcc
AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
GDB = $(TOOLPREFIX)gdb

# About compiling:
# show warining info
CFLAGS = -Wall
# auto optimise
CFLAGS += -O
# remain frame pointer in stack
CFLAGS += -fno-omit-frame-pointer
# offer debugging info
CFLAGS += -ggdb
# output relying info to a ".d" file
CFLAGS += -MD
# make riscv64 can access any address
CFLAGS += -mcmodel=medany

# About linking:
# programme entry does't have to be "main"
# not assuming any funtion as a standard library function
CFLAGS += -ffreestanding
# unknown
CFLAGS += -mno-relax
# not linking standard library
CFLAGS += -nostdlib
CFLAGS += -fno-builtin
# .common SECTION is not allowed when linking
CFLAGS += -fno-common
# header searching path
CFLAGS += -I./kernel/init -I./kernel/libs -I./kernel/trap -I./kernel/mem -I./kernel/batch -I./kernel/driver -I./kernel/proc -I./kernel/fs
# ban stack-protector if present
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
# ban PIE if present (for Ubuntu 16.10 toolchain)
# PIE generates random virtual address for safety
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]no-pie'),)
CFLAGS += -fno-pie -no-pie
endif
ifneq ($(shell $(CC) -dumpspecs 2>/dev/null | grep -e '[^f]nopie'),)
CFLAGS += -fno-pie -nopie
endif

CFLAGS	+= -march=rv64imafd

CFLAGS	+= -ffunction-sections -fdata-sections -fstrict-volatile-bitfields

# set page size
LDFLAGS = -m elf64lriscv -nostdlib --gc-sections -z max-page-size=4096 

# bootloader
K210SBI := ./bootloader/rustsbi-k210.bin
	
#=============TARGETS=============
kernel: $(OBJS) kernel.lds
	$(LD) $(LDFLAGS) -T ./tools/kernel.lds -o oskernel $(OBJS)

clean: 
	rm -f $(OBJS) $(DFILES) oskernel oskernel.bin k210.bin
	
all: kernel
	$(OBJCOPY) oskernel --strip-all -O binary oskernel.bin
	cp $(K210SBI) k210.bin
	dd if=oskernel.bin of=k210.bin bs=128K seek=1

board: k210.bin
	sudo python3 ./tools/kflash.py -p /dev/ttyUSB0 -b 1500000 k210.bin
	sudo pyserial-miniterm --eol LF --dtr 0 --rts 0 --filter direct /dev/ttyUSB0 115200

run:
	sudo pyserial-miniterm --eol LF --dtr 0 --rts 0 --filter direct /dev/ttyUSB0 115200